<?php 
/**
 * This file is part of DomAr.
 * 
 * DomAr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomAr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomAr.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
* @package DomAr
* @subpackage Parser
*/
class DomArClassParserProperty {
	
	/**
	* @param String Property name
	*/
	protected $name;
	
	/**
	* @param String Class name which property it is.
	*/
	protected $className;
	
	/**
	* @param String Original property definition
	*/
	protected $code;
	
	public function __construct( $className, $name, $code ) {
		$this->name = $name;
		$this->className = $className;
		$this->code = $code;
	}
	
	/**
	* @param DomArClassParser
	* @param Array $tokens Source class file tokens (All tokens)
	* @param Int $startTokenPosition Position where property definition starts.
	*/
	final public static function parse( DomArClassParser $class, &$tokens, &$startTokenPosition ) {
		
		$orm = array();
		if( $tokens[$startTokenPosition-2][0] == T_DOC_COMMENT )  {
			$orm = DomArAnnotationParser::parse( $tokens[$startTokenPosition-2][1], 'property', $class->file, $tokens[$startTokenPosition-2][2]);
		}

		$code = '';
		$name = '';
		$access = '';
		
		$nrOfTokens = count($tokens);

		for( $s=$startTokenPosition; $s<$nrOfTokens; $s++) {
			
			if( $tokens[$s] == ';') {
				$code .= ';';
				break;
			}
			

			if( $tokens[$s][0] == T_PUBLIC or $tokens[$s][0] == T_PROTECTED or $tokens[$s][0] == T_PRIVATE ) {
				$access = $tokens[$s][1];
			}
			
			// if its record property then it should be private!
			if( empty($orm) === false && ($tokens[$s][0] == T_PUBLIC or $tokens[$s][0] == T_PROTECTED) ) {
				$tokens[$s][0] = T_PRIVATE;
				$tokens[$s][1] = 'private';
			}
				
			// property name
			if( $tokens[$s][0] == T_VARIABLE )
				$name = substr($tokens[$s][1],1);
			
			
			// rewrite property.
			if( is_array($tokens[$s]) )
				$code .= $tokens[$s][1];
			else
				$code .= $tokens[$s];
				
		}
		$startTokenPosition = $s;


		// finalize
		$recordProperty = count($orm) > 0;
		$definition = NULL;
		foreach( $orm as $command ) {
			switch( $command['handler'] ) {
				case '__listener':
					$listener = new DomArClassParserListener( $command['listener'], $command['method'], $command['args'] );
					$listener->setPropertyName( $name );
					$class->addListener( $listener );
				break;
				case '__validator':
					$class->addValidator( $name, $command['validator'], $command['args'], (bool)$command['isMethod'] );
				break;
				default:
					$definition = $command;
				break;
			}
		}
		
		if( $recordProperty === false ) {
			$property = new DomArClassParserProperty( $class->name, $name, $code  );
		} else {
			$property = new $definition['handler']( $class->name, $access, $name, $code, $definition );
		}
		// ----------------
		
		
		return $property;
	}
	
	public function getClass() {
		return DomArClassParser::get($this->className);
	}

	public function __get( $var ) {
		return $this->$var;
	}
}
?>